
-- We don't need to see when we pick up weapons.
function GM:DontDrawPickedUp( weap )
	return true
end
GM:AddHook( "HUDWeaponPickedUp", "DontDrawPickedUp" )

-- Toggles the physgun being enabled on round changed.
function GM:SwitchPhysgun()
	local strip, give = "weapon_physgun", "weapon_ic_fakephys"
	if ( self:IsBuild() ) then strip, give = give, strip end
	
	for _, ply in pairs( player.GetAll() ) do
		local weap = ply:GetActiveWeapon()
		ply:StripWeapon( strip )
		ply:Give( give )
		if ( IsValid( weap ) && weap:GetClass() == strip ) then
			ply:SelectWeapon( give )
			
			local weap = ply:GetActiveWeapon()
			if ( IsValid( weap ) ) then
				weap:SendWeaponAnim( ACT_VM_PRIMARYATTACK )
			end
		end
	end
end
if ( SERVER ) then GM:AddHook( "RoundChanged", "SwitchPhysgun", 1 ) end

-- Removes weapons when fight round ends.
function GM:BuildRemoveWeapons()
	if !self:IsBuild() then return end
	for _, ply in pairs( player.GetAll() ) do
		for _,wpn in pairs (ply:GetWeapons()) do
			if wpn:GetClass() != "weapon_physgun" then
				ply:StripWeapon (wpn:GetClass())
			end
		end
		ply:RemoveAllAmmo ()
		ply.Equipped = false
	end
end
if ( SERVER ) then GM:AddHook( "RoundChanged", "BuildRemoveWeapons" ) end

function GM:PlayerLoadout() end

function GM:ResetPlayerEquipment( ply )
	ply.Equipped = false
end
GM:AddHook( "PlayerLoadout", "ResetPlayerEquipment" )

function GM:DisallowArmoryInBuild ( ply, ent )
	if self:IsBuild() then return true end
end
GM:AddHook( "DisallowArmoryUse", "DisallowArmoryInBuild" )

function GM:GivePhysgun( ply )
	if ( self:IsBuild() ) then
		ply:Give( "weapon_physgun" )-- In build round, spawn the player with the physgun.
	else
		ply:Give( "weapon_ic_fakephys" )
	end
end
GM:AddHook( "PlayerLoadout", "GivePhysgun" )

function GM:GiveSecondaryInFight( ply )
	if !self:IsFight() then return end
	self:IssueActiveWeapon (ply, 2, true) --issue the weapon they have in second slot
end
GM:AddHook( "PlayerLoadout", "GiveSecondaryInFight" )

-- Don't let anything be picked up unless specifically enabled.
function GM:BlockPhysgun( ply, ent )
	if ( !ent.CanPhysgunPickup ) then return false end
end
GM:AddHook( "PhysgunPickup", "BlockPhysgun" )

--This is quite complex. Players can own weapons. Any weapon they own, they can select to use. They cannot hold more than one of each weapon type.
--the term I am using for owned weapons are 'licenses'.

function GM:IssueEquipment ( ply, ent )
	printd ("Armory used ("..tostring(ply)..", "..tostring(ent)..")")
	if !ply.weapons then
		self:InitalizeWeapons (ply)
	end
	self:IssueActiveWeapons (ply)
	self:SendWeaponsMenu (ply)
end

GM:AddHook( "ArmoryUsed", "IssueEquipment" )

function GM:InitializeWeapons (ply)
	if ply:GetValue ("weapons") then
		ply.weapons = ply:GetValue ("weapons")
		ply.activeWeapons = ply:GetValue ("activeWeapons")
	else
		self:GiveFreeWeaponLicenses (ply)
		ply:SetValue ("weapons", ply.weapons)
		ply:SetValue ("activeWeapons", ply.activeWeapons)
	end
	self:SendWeaponLicenses (ply)
end

GM:AddHook( "PlayerInitialSpawn", "InitializeWeapons" )

function GM:GiveFreeWeaponLicenses (ply)
	ply.weapons = {}
	for wpntype,tbl in pairs (self.CombatWeapons) do
		for wpnid,wpn in pairs (tbl) do
			if wpn.Cost <= 0 then
				self:GiveWeaponLicense (ply, wpntype, wpnid, true)
			end
		end
	end
	ply.activeWeapons = {}
	for wpntype,tbl in pairs (ply.weapons) do
		for wpnid,wpn in pairs (tbl) do
			self:SetActiveWeapon (ply, wpntype, wpnid)
		end
	end
end

function GM:SetActiveWeapon (ply, wpntype, wpnid, nosend)
	ply.activeWeapons[wpntype] = wpnid
	if not nosend then self:SendActiveWeapon (ply, wpntype, wpnid) end
end

function GM:SendActiveWeapon (ply, wpntype, wpnid)
	umsg.Start ("WpnActive", ply)
	umsg.Short (wpntype)
	umsg.Short (wpnid)
	umsg.End ()
end

function GM:GiveWeaponLicense (ply, wpntype, wpnid)
	ply.weapons[wpntype] = ply.weapons[wpntype] or {}
	ply.weapons[wpntype][wpnid] = true
	self:SendWeaponLicense (ply, wpntype, wpnid)
end

function GM:HasWeaponLicense (ply, wpntype, wpnid)
	ply.weapons[wpntype] = ply.weapons[wpntype] or {}
	return ply.weapons[wpntype][wpnid]
end

function GM:GiveWeaponUnits (ply, wpntype, wpnid, amt)
	ply.weapons[wpntype] = ply.weapons[wpntype] or {}
	ply.weapons[wpntype][wpnid] = (ply.weapons[wpntype][wpnid] or 0) + amt
	self:SendWeaponUnits (ply, wpntype, wpnid)
	self.PurchasePerUnitWeapons = self.PurchasePerUnitWeapons or {}
	self.PurchasePerUnitWeapons[wpntype] = self.PurchasePerUnitWeapons[wpntype] or {}
	if not self.PurchasePerUnitWeapons[wpntype][wpnid] then
		self.PurchasePerUnitWeapons[wpntype][wpnid] = self.CombatWeapons[wpntype][wpnid]
	end
end

function GM:GetWeaponUnits (ply, wpntype, wpnid)
	ply.weapons[wpntype] = ply.weapons[wpntype] or {}
	return ply.weapons[wpntype][wpnid] or 0
end

function GM:SendWeaponLicenses (ply)
	printd ("send")
	umsg.Start ("WpnLicenses", ply)
	for wpntype,tbl in pairs (ply.weapons) do
		umsg.Bool (true)
		umsg.Short (wpntype) --send the type of weapons the following are in
		for wpnid,bool in pairs (tbl) do
			if bool then
				umsg.Bool (true)
				umsg.Short (wpnid)
			end
		end
		umsg.Bool (false)
	end
	umsg.Bool (false)
	umsg.End()
end

function GM:SendWeaponLicense (ply, wpntype, wpnid)
	umsg.Start ("WpnLicense", ply)
	umsg.Short (wpntype)
	umsg.Short (wpnid)
	umsg.End()
end

function GM:SendWeaponUnits (ply, wpntype, wpnid)
	printd ("send indiv units")
	umsg.Start ("WpnUnits", ply)
	umsg.Short (wpntype)
	umsg.Short (wpnid)
	umsg.Short (ply.weapons[wpntype][wpnid])
	umsg.End()
end

function GM:IssueActiveWeapons (ply)
	for _,wpn in pairs (ply:GetWeapons()) do
		if wpn:GetClass() != "weapon_ic_fakephys" then
			local rmv = not wpn.PurchasePerAmmo
			for wpntype,wpnid in pairs (ply.activeWeapons) do
				if wpn:GetClass() == self.CombatWeapons[wpntype][wpnid].ClassName then rmv = false end
			end
			if rmv then
				printd ("stripping "..wpn:GetClass())
				ply:StripWeapon (wpn:GetClass())
			end
		end
	end
	--[[for wpntype,wpnid in pairs (ply.activeWeapons) do
		local wpntable = self.CombatWeapons[wpntype][wpnid]
		--weapon
		if not ply:HasWeapon (wpntable.ClassName) then
			ply:Give (wpntable.ClassName)
		end
		--ammo
		local ammoType = wpntable.Primary.Ammo
		local targetAmount = wpntable.Primary.DefaultClip - wpntable.Primary.ClipSize
		ply:GiveAmmo (targetAmount - ply:GetAmmoCount (ammoType), ammoType)
	end]]
	for wpntype,_ in pairs (ply.activeWeapons) do
		self:IssueActiveWeapon (ply, wpntype, (wpntype == 1 and ply:GetActiveWeapon().Slot <= 2))
	end
	for wpntype,tbl in pairs (self.PurchasePerUnitWeapons) do
		for wpnid,wpntable in pairs (tbl) do
			local units = self:GetWeaponUnits (ply, wpntype, wpnid)
			if units > 0 then
				printd ("handling weapon", wpntable.ClassName)
				printd ("units", units)
				local ammoType = wpntable.Primary.Ammo
				ply:GiveAmmo (units, ammoType)
				printd ("endAmmo", ply:GetAmmoCount (ammoType))
				self:GiveWeaponUnits (ply, wpntype, wpnid, -units)
			end
		end
	end
end

function GM:IssueActiveWeapon (ply, wpntype, select)
	local wpnid = ply.activeWeapons[wpntype]
	if !wpnid then return end
	local wpntable = self.CombatWeapons[wpntype][wpnid]
	if !wpntable then return end
	wpntable = weapons.Get(wpntable.ClassName)
	
	--weapon
	local wasGiven = false
	if not ply:HasWeapon (wpntable.ClassName) then
		ply:Give (wpntable.ClassName)
		
		wasGiven = true
	end
	--ammo
	local ammoType = wpntable.Primary.Ammo
	if not wpntable.PurchasePerAmmo and not wpntable.DoNotRestock then
-- TODO: This looks sloppy, rewrite?
		if ammoType then ply:RemoveAmmo (60000, ammoType) end
		local targetAmount = wpntable.Primary.DefaultClip - wpntable.Primary.ClipSize
		if wasGiven then
			targetAmount = targetAmount + wpntable.Primary.ClipSize
			local wpn = ply:GetWeapon (wpntable.ClassName)
			if wpn:Clip1() > 0 then
				ply:GetWeapon (wpntable.ClassName):SetClip1 (0)
			end
		end
		ply:GiveAmmo (targetAmount - ply:GetAmmoCount (ammoType), ammoType)
	end
	--select
	if select then
		ply:SelectWeapon (wpntable.ClassName)
	end
end

function GM:SendWeaponsMenu (ply)
	--this is handled by the context menu button. This might instead handle special ammo.
end

function GM:PurchaseWeaponLicense (ply, wpntype, wpnid)
	if self.CombatWeapons[wpntype] and self.CombatWeapons[wpntype][wpnid] then
		local wpntable = self.CombatWeapons[wpntype][wpnid]
		
		if wpntable.PurchasePerAmmo then
			local cost = wpntable.Cost
			if cost > ply:GetValue("credits", 0) then return end
			self:GiveWeaponUnits (ply, wpntype, wpnid, 1)
			self:SpendCredits (ply, cost)
		end
		
		if self:HasWeaponLicense (ply, wpntype, wpnid) then
			printd ("Already own this.")
			--just set as active instead
			self:SetActiveWeapon (ply, wpntype, wpnid)
			return
		end
		
		local cost = wpntable.Cost
		if cost > ply:GetValue("credits", 0) then return end
		self:GiveWeaponLicense (ply, wpntype, wpnid)
		self:SpendCredits (ply, cost)
		self:SetActiveWeapon (ply, wpntype, wpnid)
	end
end

function RecvWeaponLicensePurchase (ply, cmd, args)
	if args[1] and args[2] then
		GAMEMODE:PurchaseWeaponLicense (ply, tonumber(args[1]), tonumber(args[2]))
	end
end

if ( SERVER ) then concommand.Add ("inc_purchaseweapon", RecvWeaponLicensePurchase) end